using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Transactions;
using System.Collections;
using System.Collections.Specialized;
using System.IO;

namespace Gratamira.AccesoDato
{
    public class accesoDatos
    {
        SqlConnection cn = new SqlConnection();
        SqlCommand cm = new SqlCommand();
        SqlDataAdapter da = new SqlDataAdapter();
        private static string cad;
        
        private int  _regAfectados = 0;

        public accesoDatos() {
            cn.ConnectionString = cad;    
        }

        public accesoDatos(string pSistema)
        {
            cad = Conexion.obtenerCadenaConexion(pSistema);
            cn.ConnectionString = cad;
        }

        public int regAfectados
        {
            get
            {
                return _regAfectados;
            }
            set
            {
                _regAfectados = value;
            }
        }

        public bool ejecutarLoteSQL(StringCollection sqlLista)
        {
            //Crear transaccion antes de enviar sentencia
            TransactionOptions options;
            TransactionScope scope = null;
            try
            {
                //Crear instancia del objeto que implenta la transaccion
                options = new TransactionOptions();
                options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
                options.Timeout = new TimeSpan(0, 3, 0);
                scope = new TransactionScope(TransactionScopeOption.Required, options);
                //Establecer conexion
                cn.Open();
                cm.Connection = cn;
                //Ejecutar lsita de comandos
                foreach (Object mSql in sqlLista)
                {
                    cm.CommandText = mSql.ToString();
                    cm.ExecuteNonQuery();
                }
                //Finalizar transaccion exitosamente
                scope.Complete();
            }
            catch (SqlException ex)
            {
                //Es un error de sql, validar si es llave duplica por el codigo
                if (ex.Number == 2627)
                {
                    throw new Exception("Existe un Codigo Duplicado.", ex);
                }
                else if (ex.Number == 2601)
                {
                    throw new Exception("Existe un nombre o llave Duplicada.", ex);
                }
                else if (ex.Number == 547)
                {
                    throw new Exception("Se hace referencia a este registro en otra tabla.", ex);
                }
                else
                {
                    throw new Exception("Ocurrion un problema en la base de datos." + ex.Message, ex);
                }
                //return 0;
            }
            catch (Exception exp)
            {
                throw new Exception(exp.Message);
            }
            finally
            {
                //Si se elimina la referencia sin antes confirmar, esta realiza un Rollback
                scope.Dispose();
                if (cn.State == ConnectionState.Open)
                {
                    cn.Close();
                }
            }
            return true;
        }


        public bool ejecutarListaSQL(StringCollection sqlLista)
        {
            cn.Open();
            cm.Connection = cn;
            foreach (Object mSql in sqlLista)
            {
                cm.CommandText = mSql.ToString();
                cm.ExecuteNonQuery();
            }
            cn.Close();
            return true;
        }

        public int ejecutarSQL(string sqlStr, string sistema) {
            try
            {
                cn.Open();
                cm.Connection = cn;
                cm.CommandText = sqlStr;
                regAfectados = cm.ExecuteNonQuery();
                cn.Close();
                return regAfectados;
            }
            catch (SqlException ex)
            {
                //Es un error de sql, validar si es llave duplica por el codigo
                if (ex.Number == 2627)
                {
                    throw new Exception("Existe un Codigo Duplicado.", ex);
                }
                else if (ex.Number == 2601)
                {
                    throw new Exception("Existe un nombre o llave Duplicada.", ex);
                }
                else if (ex.Number == 547)
                {
                    throw new Exception("Se hace referencia a este registro en otra tabla.", ex);
                }
                else
                {
                    throw new Exception("Ocurrion un problema en la base de datos." + ex.Message, ex);
                }
                //return 0;
            }
        }

        public  DataTable leerDatosSQL(string sqlStr, string sistema) {

            try
            {
                DataTable dt = new DataTable();
                cn.Open();
                cm.Connection = cn;
                cm.CommandText = sqlStr;
                da.SelectCommand = cm;
                da.Fill(dt);
                cn.Close();
                regAfectados = dt.Rows.Count;
                return dt;
            }
            catch (SqlException ex)
            {
                //Es un error de sql, validar si es llave duplica por el codigo
                if (ex.Number == 18456)
                {
                    throw new Exception(" Cadena de conexion errada. User. Favor contactar soporte tecnico de Softpro.", ex);
                }
                else
                {
                    throw new Exception("Ocurrion un problema en la base de datos." + ex.Message, ex);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            
        }

        public string  leerValorSQL(string sqlStr, string sistema)
        {
            string vDevolver;
            cn.Open();
            cm.Connection = cn;
            cm.CommandText = sqlStr;
            vDevolver = cm.ExecuteScalar().ToString();
            cn.Close();
            return vDevolver;
        }

        public void insertarXML(string pNombreProcedimiento, DataSet dsRegistros) 
        {
            if (dsRegistros != null)
            {

                SqlParameter param = new SqlParameter();
                string detalleXML = "";

                param = new SqlParameter("@datos", SqlDbType.NText);


                //Crear el XML

                detalleXML = dsRegistros.GetXml();

                param.Value = detalleXML;

                SqlCommand objCom = new SqlCommand();

                cn.Open();
                objCom.Connection = cn;


                objCom.CommandType = CommandType.StoredProcedure;
                objCom.CommandText = pNombreProcedimiento;


                objCom.Parameters.Add(param);

                try
                {
                    objCom.ExecuteNonQuery();
                }
                catch (SqlException ex)
                {
                    //Es un error de sql, validar si es llave duplica por el codigo
                    if (ex.Number == 2627)
                    {
                        throw new Exception("Existe un Codigo Duplicado.", ex);
                    }
                    else if (ex.Number == 2601)
                    {
                        throw new Exception("Existe un nombre o llave Duplicada.", ex);
                    }
                    else
                    {
                        throw new Exception("Ocurrio un problema en la base de datos." + ex.Message, ex);
                    }
                }
            }
            else
            {
                throw new ArgumentNullException("dsRegistros");
            }
        }

        public void insertarXML(string pNombreProcedimiento, string detalleXML, ref string pRegresarXML)
        {
            SqlParameter[] param = new SqlParameter[2];

            param[0] = new SqlParameter("@datos", SqlDbType.NText);
            param[1] = new SqlParameter("@xml", SqlDbType.VarChar, 8000);
            param[1].Direction = ParameterDirection.Output;


            param[0].Value = detalleXML;
            param[1].Value = pRegresarXML;

            SqlCommand objCom = new SqlCommand();

            cn.Open();
            objCom.Connection = cn;


            objCom.CommandType = CommandType.StoredProcedure;
            objCom.CommandText = pNombreProcedimiento;

            objCom.Parameters.Add(param[0]);
            objCom.Parameters.Add(param[1]);

            try
            {
                objCom.ExecuteNonQuery();
                string repR = "\r";
                string repN = "\n";

                pRegresarXML = param[1].Value.ToString().Replace("\\r", repR);
                pRegresarXML = pRegresarXML.Replace("\\n", repN);
            }
            catch (SqlException ex)
            {
                //Es un error de sql, validar si es llave duplica por el codigo
                if (ex.Number == 2627)
                {
                    throw new Exception("Existe un Codigo Duplicado.", ex);
                }
                else if (ex.Number == 2601)
                {
                    throw new Exception("Existe un nombre o llave Duplicada.", ex);
                }
                else
                {
                    throw new Exception("Ocurrio un problema en la base de datos." + ex.Message, ex);
                }
            }
        }

        public void insertarSP(string pNombreProcedimiento, string pBodegaID, string pUsuarioID)
        {
            SqlParameter[] param = new SqlParameter[2];

            param[0] = new SqlParameter("@BodegaID", SqlDbType.VarChar, 8);
            param[1] = new SqlParameter("@UsuarioID", SqlDbType.VarChar, 16);
            
            param[0].Value = pBodegaID;
            param[1].Value = pUsuarioID;
            
            SqlCommand objCom = new SqlCommand();

            cn.Open();
            objCom.Connection = cn;

            objCom.CommandType = CommandType.StoredProcedure;
            objCom.CommandText = pNombreProcedimiento;

            objCom.Parameters.Add(param[0]);
            objCom.Parameters.Add(param[1]);

            try
            {
                objCom.ExecuteNonQuery();
            }
            catch (SqlException ex)
            {
                //Es un error de sql, validar si es llave duplica por el codigo
                if (ex.Number == 2627)
                {
                    throw new Exception("Existe un Codigo Duplicado.", ex);
                }
                else if (ex.Number == 2601)
                {
                    throw new Exception("Existe un nombre o llave Duplicada.", ex);
                }
                else
                {
                    throw new Exception("Ocurrio un problema en la base de datos." + ex.Message, ex);
                }
            }
        }

    }
}
